using System.Collections.Generic;
using LeetCodeQuestionBank.Models;
using Xunit;
using Newtonsoft.Json;

namespace LeetCodeQuestionBank.Algorithm
{
    public class No0092_ReverseBetween
    {
        /*
        反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
        说明:
            1 ≤ m ≤ n ≤ 链表长度。
        示例:
            输入: 1->2->3->4->5->NULL, m = 2, n = 4
            输出: 1->4->3->2->5->NULL
        */


        public static IEnumerable<object[]> GetTestArgs()
        {
            return new object[][] {
                new object[] {
                    2, 4,
                    new ListNode(1,
                        new ListNode(2,
                            new ListNode(3,
                                new ListNode(4,
                                    new ListNode(5)
                                )
                            )
                        )
                    ),
                    new ListNode(1,
                        new ListNode(4,
                            new ListNode(3,
                                new ListNode(2,
                                    new ListNode(5)
                                )
                            )
                        )
                    ),
                },
            };
        }

        [Theory]
        [MemberData(nameof(GetTestArgs))]
        public void ReverseBetween_OnExecuteTest(int left, int right, ListNode head, ListNode head_result)
        {
            Assert.Equal(head_result, ReverseBetween(head, left, right));
        }

        public ListNode ReverseBetween(ListNode head, int left, int right)
        {
            ListNode dummyNode = new ListNode(-1);
            dummyNode.next = head;
            ListNode pre = dummyNode;
            for (int i = 0; i < left - 1; i++)
            {
                pre = pre.next;
            }
            ListNode cur = pre.next;
            ListNode next;
            for (int i = 0; i < right - left; i++)
            {
                next = cur.next;
                cur.next = next.next;
                next.next = pre.next;
                pre.next = next;
            }
            return dummyNode.next;
        }
    }
}
